package com.cwn.wizbank.utils.xml;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.transform.stream.StreamSource;
import java.io.Serializable;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author rain
 * @date 2019/09/04
 */
public abstract class JaxbUtils implements Serializable {
    public final static Map<Class<?>, JAXBContext> contextMap = new ConcurrentHashMap<>();


    public static String convertToXml(Object obj, boolean containHeader) throws JAXBException {
        final Class<?> clazz;
        if (obj instanceof JAXBElement) {
            clazz = ((JAXBElement<?>) obj).getDeclaredType();
        } else {
            clazz = obj.getClass();
        }
        StringWriter writer = new StringWriter();
        Marshaller marshaller = getContext(clazz).createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, !containHeader);
        marshaller.marshal(obj, writer);
        return writer.toString();
    }

    /**
     * 将xml解析成指定对象
     *
     * @param xml   xml数据
     * @param clazz 对象
     * @param <T>   对象
     * @return 对象
     * @throws JAXBException 异常处理
     */
    public static <T> T convertToJavaBean(String xml, Class<T> clazz) throws JAXBException {
        StringReader reader = new StringReader(xml);
        return (T) (getContext(clazz).createUnmarshaller().unmarshal(new StreamSource(reader)));
    }

    public static JAXBContext getContext(Class<?> clazz) throws JAXBException {
        JAXBContext context = contextMap.get(clazz);
        if (context == null) {
            context = JAXBContext.newInstance(clazz);
            contextMap.put(clazz, context);
        }
        return context;
    }
}
